#region Apache Notice
/*****************************************************************************
 * $Header: $
 * $Revision: 602985 $
 * $Date: 2007-12-10 11:25:11 -0700 (Mon, 10 Dec 2007) $
 * 
 * iBATIS.NET Data Mapper
 * Copyright (C) 2004 - Gilles Bayon
 *  
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 ********************************************************************************/
#endregion

#region Using

using System.Collections;
#if NET_2_0
using System.Collections.Generic;
#endif
using System.Data;
using IBatisNet.DataMapper.Commands;
using IBatisNet.DataMapper.Configuration.Cache;
using IBatisNet.DataMapper.Configuration.Statements;
using IBatisNet.DataMapper.Scope;

#endregion 

namespace IBatisNet.DataMapper.MappedStatements
{
	/// <summary>
	/// Summary description for CachingStatement.
	/// </summary>
    public sealed class CachingStatement : IMappedStatement
	{
		private MappedStatement _mappedStatement =null;

		/// <summary>
		/// Event launch on exceute query
		/// </summary>
		public event ExecuteEventHandler Execute;

		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="statement"></param>
        public CachingStatement(MappedStatement statement) 
		{
			_mappedStatement = statement;
		}

		#region IMappedStatement Members


		///// <summary>
		///// The IPreparedCommand to use
		///// </summary>
		//public IPreparedCommand PreparedCommand
		//{
		//	get { return _mappedStatement.PreparedCommand; }
		//}

		/// <summary>
		/// Name used to identify the MappedStatement amongst the others.
		/// This the name of the SQL statment by default.
		/// </summary>
		public string Id
		{
			get { return _mappedStatement.Id; }
		}

		/// <summary>
		/// The SQL statment used by this MappedStatement
		/// </summary>
		public IStatement Statement
		{
			get { return _mappedStatement.Statement; }
		}

		/// <summary>
		/// The SqlMap used by this MappedStatement
		/// </summary>
		public ISqlMapper SqlMap
		{
			get {return _mappedStatement.SqlMap; }
		}

		 

       
		#endregion

		/// <summary>
		/// Gets a percentage of successful cache hits achieved
		/// </summary>
		/// <returns>The percentage of hits (0-1), or -1 if cache is disabled.</returns>
		public double GetDataCacheHitRatio() 
		{
			if (_mappedStatement.Statement.CacheModel != null) 
			{
				return _mappedStatement.Statement.CacheModel.HitRatio;
			} 
			else 
			{
				return -1;
			}
		}

        /// <summary>
        /// Gets the cache key.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns>the cache key</returns>
		private CacheKey GetCacheKey(RequestScope request) 
		{
			CacheKey cacheKey = new CacheKey();
			int count = request.IDbCommand.Parameters.Count;
			for (int i = 0; i < count; i++) 
			{
				IDataParameter dataParameter = (IDataParameter)request.IDbCommand.Parameters[i];
				if (dataParameter.Value != null) 
				{
					cacheKey.Update( dataParameter.Value );
				}
			}
			
			cacheKey.Update(_mappedStatement.Id);
			//cacheKey.Update(_mappedStatement.SqlMap.DataSource.ConnectionString);
			cacheKey.Update(request.IDbCommand.CommandText);

			CacheModel cacheModel = _mappedStatement.Statement.CacheModel;
			if (!cacheModel.IsReadOnly && !cacheModel.IsSerializable) 
			{
				cacheKey.Update(request);
			}
			return cacheKey;
		}
	}
}
